Conversation
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR refactors the source generation helper library by reorganizing and simplifying the fluent API's generator infrastructure. The primary goal is to decouple the recording and mock implementations, make Generate.CurrentGenerator internal (using reflection to set it during generation), and introduce a proper IMethodBuilder interface alongside IGeneratorsFactory. It also adds two new test cases covering default-case constant-value generation via both the attribute-based and fluent APIs.
Changes:
- Extracted interfaces
IMethodBuilder,IMethodBuilder<TArg1>, andIGeneratorsFactoryinto separate files; movedMethodBuilderimplementations to their own file. - Replaced the
EmptyGeneratorsFactory-based default inGenerate.CurrentGeneratorwith a new no-opMockGeneratorsFactory, and changed the property frompublictointernal(updating the generator's reflection binding flags accordingly). - Removed the
Integer.Rangehelper; callers now pass plain arrays. Added new tests (DefaultCaseConstValue,DefaultCaseConstValueFluent) covering the default-case-only switch generation path.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
MattSourceGenHelpers.Abstractions/Generate.cs |
Slimmed down: removed inlined interfaces/classes; CurrentGenerator changed to internal with MockGeneratorsFactory default |
MattSourceGenHelpers.Abstractions/IGeneratorsFactory.cs |
New file: extracted IGeneratorsFactory interface (added ForMethod(), removed non-generic CreateImplementation()) |
MattSourceGenHelpers.Abstractions/IMethodBuilder.cs |
New file: extracted IMethodBuilder and IMethodBuilder<TArg1> interfaces |
MattSourceGenHelpers.Abstractions/MethodBuilder.cs |
New file: extracted MethodBuilder and MethodBuilder<TArg1> implementations |
MattSourceGenHelpers.Abstractions/Mocks.cs |
New file: MockGeneratorsFactory and mock chain as no-op runtime implementations |
MattSourceGenHelpers.Abstractions/RecordingGeneratorsFactory.cs |
Refactored to use primary constructors and added ForMethod() delegation; recording classes simplified |
MattSourceGenHelpers.Abstractions/Assembly.cs |
New file: InternalsVisibleTo for Tests and Generators assemblies |
MattSourceGenHelpers.Abstractions/SwitchCase.cs |
Reformatted and made arg1 required (breaking change) |
MattSourceGenHelpers.Abstractions/IMethodImplementationGenerator.cs |
Removed unused IMethodImplementationGeneratorVoid interface; added [UsedImplicitly] |
MattSourceGenHelpers.Abstractions/IMethodGenerator.cs |
Deleted empty interface |
MattSourceGenHelpers.Abstractions/Integer.cs |
Deleted Integer.Range helper |
MattSourceGenHelpers.Abstractions/PartialMethodCalledDuringGenerationException.cs |
Converted to primary constructor syntax |
MattSourceGenHelpers.Generators/GeneratesMethodExecutionRuntime.cs |
Updated reflection binding flags to NonPublic for CurrentGenerator; used nameof for property reflection lookups |
MattSourceGenHelpers.Tests/DefaultCaseConstValue.cs |
New test file: attribute-based default-case constant-value generation |
MattSourceGenHelpers.Tests/DefaultCaseConstValueFluent.cs |
New test file: fluent-API default-case constant-value generation |
MattSourceGenHelpers.Tests/PiExampleFluentTests.cs |
Replaced Integer.Range(300, 303) with inline array new[]{300, 301, 302, 303} |
MattSourceGenHelpers.Examples/PiExampleFluent.cs |
Same Integer.Range → inline array replacement in example |
MattSourceGenHelpers.sln.DotSettings.user |
IDE user settings update (session ID change, 5 extra blank lines) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| [UsedImplicitly] | ||
| public List<object> CaseKeys { get; } = new(); | ||
| [UsedImplicitly] | ||
| public List<object?> CaseValues { get; } = new(); |
There was a problem hiding this comment.
HasDefaultCase is accessed via reflection (in GeneratesMethodExecutionRuntime.cs line 290) just like CaseKeys and CaseValues, yet it is missing the [UsedImplicitly] annotation that was added to the other two properties. This is inconsistent and may cause a JetBrains inspection warning on HasDefaultCase.
| public List<object?> CaseValues { get; } = new(); | |
| public List<object?> CaseValues { get; } = new(); | |
| [UsedImplicitly] |
| public IMethodImplementationGenerator<TReturnType> WithReturnType<TReturnType>() => new MockImplementationGenerator<TReturnType>(); | ||
| } | ||
|
|
||
| public class MockImplementationGenerator<TReturnType> : IMethodImplementationGenerator<TReturnType> | ||
| { | ||
| public IMethodImplementationGenerator UseBody(Func<object> body) => this; | ||
| } | ||
|
|
There was a problem hiding this comment.
There are two classes implementing IMethodImplementationGenerator<TReturnType> with nearly identical implementations but different names: MockMethodImplementationGenerator<TReturnType> (line 13) and MockImplementationGenerator<TReturnType> (line 59). The second is used by MockMethodBuilder.WithReturnType<TReturnType>() but could simply reuse MockMethodImplementationGenerator<TReturnType>, eliminating the duplication and inconsistent naming.
| public IMethodImplementationGenerator<TReturnType> WithReturnType<TReturnType>() => new MockImplementationGenerator<TReturnType>(); | |
| } | |
| public class MockImplementationGenerator<TReturnType> : IMethodImplementationGenerator<TReturnType> | |
| { | |
| public IMethodImplementationGenerator UseBody(Func<object> body) => this; | |
| } | |
| public IMethodImplementationGenerator<TReturnType> WithReturnType<TReturnType>() => new MockMethodImplementationGenerator<TReturnType>(); | |
| } |
| object? arg1 = null | ||
| ) | ||
| : Attribute | ||
| public class SwitchCase(object? arg1) : Attribute |
There was a problem hiding this comment.
The arg1 parameter of SwitchCase was previously optional (object? arg1 = null). In this PR it is now required (object? arg1). Since SwitchCase is a public attribute, this is a breaking API change for any external consumer using [SwitchCase] without an argument. If this attribute is intended to be a public API, consider documenting this breaking change or preserving the optional default.
| public class SwitchCase(object? arg1) : Attribute | |
| public class SwitchCase(object? arg1 = null) : Attribute |
|
|
||
|
|
||
|
|
||
|
|
||
|
|
There was a problem hiding this comment.
Five extra blank lines (lines 17–21) were added to the <wpf:ResourceDictionary> XML element. These are stale IDE artifacts and add no value. They should be removed to keep the settings file clean.
| public void PiExampleLikeGenerator_ProducesExpectedRuntimeOutput(int decimalNumber, int expectedDigit) | ||
| { | ||
| int result = DefaultCaseConstValueClass.Foo(decimalNumber); | ||
|
|
||
| Assert.That(result, Is.EqualTo(expectedDigit)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void PiExampleLikeGenerator_ProducesExpectedGeneratedCode() |
There was a problem hiding this comment.
The test methods in both DefaultCaseConstValue and DefaultCaseConstValueFluent are named PiExampleLikeGenerator_ProducesExpectedRuntimeOutput and PiExampleLikeGenerator_ProducesExpectedGeneratedCode, which appear to be copied from the Pi example tests. These tests have nothing to do with the Pi example — they test default-case constant-value generation. The method names should be updated to reflect what's actually being tested (e.g., DefaultCaseWithConstValue_ProducesExpectedRuntimeOutput / DefaultCaseWithConstValue_ProducesExpectedGeneratedCode).
| public void PiExampleLikeGenerator_ProducesExpectedRuntimeOutput(int decimalNumber, int expectedDigit) | ||
| { | ||
| int result = DefaultCaseConstValueFluentClass.Foo(decimalNumber); | ||
|
|
||
| Assert.That(result, Is.EqualTo(expectedDigit)); | ||
| } | ||
|
|
||
| [Test] | ||
| public void PiExampleLikeGenerator_ProducesExpectedGeneratedCode() |
There was a problem hiding this comment.
The test methods in DefaultCaseConstValueFluent are named PiExampleLikeGenerator_ProducesExpectedRuntimeOutput and PiExampleLikeGenerator_ProducesExpectedGeneratedCode, which appear to be copied from the Pi example tests. These tests have nothing to do with Pi — they test default-case constant-value generation using the fluent API. The method names should be updated to reflect what's actually being tested (e.g., DefaultCaseWithConstValue_ProducesExpectedRuntimeOutput / DefaultCaseWithConstValue_ProducesExpectedGeneratedCode).
| public IMethodImplementationGenerator CreateImplementation() | ||
| { | ||
| var record = new SwitchBodyRecord(); | ||
| SwitchBodyRecord record = new SwitchBodyRecord(); | ||
| LastRecord = record; | ||
| return new RecordingMethodImplementationGenerator(record); | ||
| return new RecordingMethodImplementationGenerator(); | ||
| } |
There was a problem hiding this comment.
The non-generic CreateImplementation() method in RecordingGeneratorsFactory is no longer part of the IGeneratorsFactory interface (which was updated in this PR to remove the non-generic overload) and is never called anywhere in the codebase. This is dead code that should be removed to avoid confusion.
No description provided.